package trading.web;

import java.util.Timer;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import trading.algo.MasterAlgo;
import trading.algo.MasterAlgoStartUpTask;
import trading.algo.OpenOrdersTask;
import trading.algo.TimerKillerTask;
import trading.algo.UpdateAccountValueTask;
import trading.algo.APIConnectivityTask.APIConnectMasterTask;
import trading.algo.initTask.HistoricalLowTask;
import trading.algo.initTask.LastClosePriceTask;
import trading.algo.initTask.MarketStatusTask;
import trading.bo.DBAccessorBO;
import trading.bo.IBAccessorBO;
import trading.dataentry.MonitoredStocks;
import trading.util.IBAPI;

import com.ib.client.EClientSocket;

@Controller
public class ActivateProcessController {

	@Resource
	private IBAPI ibAPI;

	@Resource
	private IBAccessorBO ibAccessorBO;

	@Resource
	private DBAccessorBO dbAccessorBO;
	
	@Resource
	private MasterAlgo masterAlgo;

	public class URLPrefix {
		public static final String ACTIVATION = "/activate";
		public static final String SYNC_LAST_PRICE = ACTIVATION + "/lastPrice";
		public static final String SYNC_HIST_LOW_PRICE = ACTIVATION
				+ "/histLowPrice";
	}

	/**
	 * Start up IB connection, sync portfolio with DB, sync share price with DB
	 * 
	 * @return
	 * @throws InterruptedException
	 */
	@RequestMapping(value = { URLPrefix.ACTIVATION }, method = RequestMethod.GET)
	public ModelAndView activateIBSystem() throws InterruptedException {
//		EClientSocket m_client = ibAPI.getClient();
//
//		// Connecting
//		String connectionMsg;
//		if (ibAccessorBO.connect()) {
//			connectionMsg = "Connected to Tws server version "
//					+ m_client.serverVersion() + " at "
//					+ m_client.TwsConnectionTime();
//		} else {
//			connectionMsg = "Connection failed.";
//		}

		Timer timer = new Timer();
		
		int taskID = 0;
		// Connect to IB
        APIConnectMasterTask apiConnectMasterTask = new APIConnectMasterTask(ibAccessorBO);
        timer.schedule(apiConnectMasterTask, taskID * 1000);
        taskID += APIConnectMasterTask.secondsNeeded();
        
		// sync the last closing price of stock tickers
		for (int i = 0; i < MonitoredStocks.TICKERS.values().length; i++, taskID += 3) {
			MonitoredStocks.TICKERS ticker = MonitoredStocks.TICKERS.values()[i];
		    timer.schedule(new LastClosePriceTask(ticker.name(), ibAccessorBO), taskID * 1000);
		}
		
		// sync the date of stock historical low price
		for (int i = 0; i < MonitoredStocks.TICKERS.values().length; i++, taskID += 3) {
			MonitoredStocks.TICKERS ticker = MonitoredStocks.TICKERS.values()[i];
			timer.schedule(new HistoricalLowTask(ticker.name(), ibAccessorBO), taskID * 1000);
		}
		
		// sync the account status and portfolio positions
		timer.schedule(new UpdateAccountValueTask(ibAccessorBO, dbAccessorBO, true), taskID*1000);
		taskID += 5;
		
		// sync the open orders
		timer.schedule(new OpenOrdersTask(ibAccessorBO, dbAccessorBO), taskID*1000);
		taskID++;
		
		// sync market status
		timer.schedule(new MarketStatusTask(MonitoredStocks.TICKERS.UVXY.name(), ibAccessorBO), taskID*1000);
		taskID += 5;
		
        // start up the master algo
		timer.schedule(new MasterAlgoStartUpTask(this.masterAlgo), taskID*1000);
		taskID++;
		
		// kill the timer
		timer.schedule(new TimerKillerTask(timer), taskID*1000);
		
		
		return new ModelAndView("activate", new ModelMap());
	}


	@RequestMapping(value = { URLPrefix.SYNC_LAST_PRICE }, method = RequestMethod.GET)
	public ModelAndView syncLastPrice(HttpServletRequest request) {
		ModelMap mm = new ModelMap();
		Integer count;
		try {
			count = Integer.parseInt(request.getParameter("num"));
		} catch (Exception e) {
			mm.addAttribute("msg", "");
			return new ModelAndView("jsonView", mm);
		}
		MonitoredStocks.TICKERS[] tickers = MonitoredStocks.TICKERS.values();
		if (tickers.length <= count) {
			mm.addAttribute("msg", "");
		} else {
			ibAccessorBO.reqLastCloseStockTickPrice(tickers[count].name());
			mm.addAttribute("msg", "continue");
		}
		return new ModelAndView("jsonView", mm);
	}
}
